/*
 * Copyright (c) 2008, Spagettikod | Stockholm
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the Spagettikod | Stockholm nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.spagettikod.t437;

import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class PreferencesDialog extends JDialog implements ActionListener, CaretListener
{
	private static final Log log = LogFactory.getLog(PreferencesDialog.class);

	private static final long serialVersionUID = -8468841142185398086L;

	private final JTextField accessKeyField = new JTextField(20);

	private final JTextField secretKeyField = new JTextField(32);

	private final JTextField serverField = new JTextField(20);

	private final JTextField portField = new JTextField(5);

	private final JLabel accessKeyLabel = new JLabel("Access Key:");

	private final JLabel secretKeyLabel = new JLabel("Secret Access Key:");

	private final JLabel serverLabel = new JLabel("Server:");

	private final JLabel portLabel = new JLabel("Server Port (empty for default):");

	private final JButton okButton = new JButton("OK");

	private final JButton cancelButton = new JButton("Cancel");

	private final JCheckBox saveSecretCheckBox = new JCheckBox("Remember secret access key");

	private final JCheckBox secureConnectionCheckBox = new JCheckBox("Use secure connection");

	private final JCheckBox showRowNumbers = new JCheckBox("Show row number column");

	private final JCheckBox changeBackgroundColor = new JCheckBox("Change background on cells with multiple attributes");

	private Configurator config;

	private JPanel createGeneralPanel()
	{
		JPanel panel = new JPanel(new GridBagLayout());

		panel.setBorder(new TitledBorder(new EtchedBorder(), "SimpleDB"));

		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.NORTHWEST;
		c.insets = new Insets(0, 5, 0, 5);
		c.gridx = 0;
		c.gridy = 0;
		c.weightx = 1.0;
		c.weighty = 0;
		panel.add(showRowNumbers, c);
		showRowNumbers.addActionListener(this);
		showRowNumbers.setActionCommand("showRowNumbers");
		showRowNumbers.setSelected(config.isSDBRowNumberShown());

		c.insets = new Insets(0, 5, 5, 5);
		c.gridy = 1;
		c.weighty = 1.0;
		panel.add(changeBackgroundColor, c);
		changeBackgroundColor.addActionListener(this);
		changeBackgroundColor.setActionCommand("changeBackgroundColor");
		changeBackgroundColor.setSelected(config.getSDBMultipleBackgroundColorize());

		return panel;
	}

	private JPanel createAccessPanel()
	{
		JPanel panel = new JPanel(new GridBagLayout());

		panel.setBorder(new TitledBorder(new EtchedBorder(), "Access Keys"));

		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.LINE_START;
		c.insets = new Insets(5, 5, 5, 5);
		c.gridx = 0;
		c.gridy = 0;
		panel.add(accessKeyLabel, c);

		c.gridx = 1;
		c.weightx = 1.0;
		panel.add(accessKeyField, c);
		accessKeyField.setText(config.getAccessKey());
		accessKeyField.setActionCommand("accessKeyField");
		accessKeyField.addCaretListener(this);

		c.gridx = 0;
		c.gridy = 1;
		c.weightx = 0;
		panel.add(secretKeyLabel, c);

		c.gridx = 1;
		c.weightx = 1.0;
		panel.add(secretKeyField, c);
		secretKeyField.setText(config.getSecretKey());
		secretKeyField.setActionCommand("secretKeyField");
		secretKeyField.addCaretListener(this);

		c.gridy = 2;
		c.gridwidth = 2;
		c.weightx = 0;
		panel.add(saveSecretCheckBox, c);
		saveSecretCheckBox.addActionListener(this);
		saveSecretCheckBox.setActionCommand("saveSecret");
		saveSecretCheckBox.setSelected(config.isSecretKeySaved());

		return panel;
	}

	private JPanel createAdvancedPanel()
	{
		JPanel panel = new JPanel(new GridBagLayout());
		panel.setBorder(new TitledBorder(new EtchedBorder(), "Server"));

		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.LINE_START;
		c.insets = new Insets(5, 5, 5, 5);
		c.gridx = 0;
		c.gridy = 0;
		panel.add(serverLabel, c);

		c.gridx = 1;
		c.weightx = 1.0;
		panel.add(serverField, c);
		serverField.setText(config.getSDBServerURL());

		c.gridx = 0;
		c.gridy = 1;
		c.weightx = 0;
		panel.add(portLabel, c);

		c.gridx = 1;
		c.weightx = 1.0;
		panel.add(portField, c);
		portField.setText(String.valueOf(config.getSDBServerPort()));

		c.gridy = 2;
		c.anchor = GridBagConstraints.LINE_START;
		panel.add(secureConnectionCheckBox, c);
		secureConnectionCheckBox.setSelected(config.isSDBSecureConnection());

		return panel;
	}

	private JPanel createButtonPanel()
	{
		JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));

		cancelButton.setActionCommand("cancel");
		cancelButton.addActionListener(this);
		cancelButton.setMnemonic(KeyEvent.VK_C);

		okButton.setActionCommand("ok");
		okButton.addActionListener(this);
		okButton.setMnemonic(KeyEvent.VK_O);
		validateOKButton();

		panel.add(okButton);
		panel.add(cancelButton);

		return panel;
	}

	public PreferencesDialog(Frame parent, Configurator config)
	{
		super(parent, true);

		this.setTitle("Preferences");

		this.config = config;

		JTabbedPane tab = new JTabbedPane();

		JPanel generalPanel = new JPanel(new GridBagLayout());
		JPanel awsPanel = new JPanel(new GridBagLayout());
		JPanel advancedPanel = new JPanel(new GridBagLayout());

		GridBagConstraints c = new GridBagConstraints();
		c.anchor = GridBagConstraints.NORTHWEST;
		c.insets = new Insets(6, 6, 6, 6);
		c.weightx = 1.0;
		c.weighty = 1.0;
		c.fill = GridBagConstraints.BOTH;

		generalPanel.add(createGeneralPanel(), c);
		awsPanel.add(createAccessPanel(), c);
		advancedPanel.add(createAdvancedPanel(), c);

		tab.addTab("General", generalPanel);
		tab.addTab("Amazon Web Services", awsPanel);
		tab.addTab("Advanced", advancedPanel);

		if (config.getAccessKey() == null || config.getSecretKey() == null || config.getSecretKey().isEmpty()
				|| config.getAccessKey().isEmpty())
		{
			tab.setSelectedIndex(1);
		}

		JPanel configPane = new JPanel(new GridBagLayout());

		c = new GridBagConstraints();
		c.insets = new Insets(8, 8, 4, 8);
		c.fill = WIDTH;
		c.gridx = 0;
		c.gridy = 0;
		configPane.add(tab);

		c.gridy = 1;
		configPane.add(createButtonPanel(), c);

		getContentPane().add(configPane);

		setLocation(parent.getX() + 22, parent.getY() + 22);
		setResizable(false);

		getRootPane().setDefaultButton(cancelButton);

		pack();
		setVisible(true);
	}

	private void validateOKButton()
	{
		if (accessKeyField.getText().equals("") || secretKeyField.getText().equals(""))
		{
			okButton.setEnabled(false);
		}
		else
		{
			okButton.setEnabled(true);
		}
	}

	public void actionPerformed(ActionEvent e)
	{
		log.debug(e.getActionCommand());
		if ("cancel".equals(e.getActionCommand()))
		{
			this.dispose();
		}
		else if ("ok".equals(e.getActionCommand()))
		{
			config.setAccessKey(accessKeyField.getText());
			config.setSecretKey(secretKeyField.getText());
			config.setSaveSecretKey(saveSecretCheckBox.isSelected());
			if (serverField.getText().toLowerCase().startsWith("https://"))
			{
				serverField.setText(serverField.getText().substring(8));
			}
			else if (serverField.getText().toLowerCase().startsWith("http://"))
			{
				serverField.setText(serverField.getText().substring(7));
			}
			config.setSDBShowRowNumber(showRowNumbers.isSelected());
			config.setSDBMultipleBackgroundColorize(changeBackgroundColor.isSelected());
			config.setSDBServerULR(serverField.getText());
			config.setSDBSecureConnection(secureConnectionCheckBox.isSelected());
			try
			{
				if (portField.getText().length() == 0)
				{
					config.setSDBServerPort(config.getDefaultSDBServerPort());
				}
				else
				{
					config.setSDBServerPort(Integer.parseInt(portField.getText()));
				}
			}
			catch (NumberFormatException nfe)
			{
				T437
						.displayErrorMessage(
								"Incorrect format",
								portField.getText()
										+ " is not a valid port number, please enter a number between 0 and 65535 or leave empty for default.");
				return;
			}
			config.save();
			this.dispose();
		}
	}

	public void caretUpdate(CaretEvent e)
	{
		validateOKButton();
	}
}